package algorithm.poj.p1000;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * [0, n)中被取出的数有X[n]个，那么[a, b]至少取出两个数等价于：
 * X[b+1]-X[a] >= 2, 即 X[a] - X[b+1] <= -2
 * 
 * 并且隐含以下条件：
 * 当i < j时，
 * X[i] - X[j] <= 0 	
 * X[j] - X[i] <= j-i
 * （在实际编程时，我们只需要添加相邻节点的隐含条件就可以，这是因为这个不等式具有可加性）
 * 
 * 求解X[m]的最小值，m是最大的区间端点
 * 
 * 问题转化成差分约束系统。
 * 使用Bellman-Ford算法可以保证max(X)-min(X)最小，和我们的目标一致。
 * 
 * @author Administrator
 *
 */
public class P1716 {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {

		InputStream input = null;
		if (false) {
			input = System.in;
		} else {
			URL url = P1716.class.getResource("P1716.txt");
			File file = new File(URLDecoder.decode(url.getPath(), "UTF-8"));
			input = new FileInputStream(file);
		}
		
		BufferedReader stdin = new BufferedReader(new InputStreamReader(input));

		StringTokenizer st = null;
		String line = stdin.readLine();
		int n = Integer.valueOf(line.trim());
		Interval[] intervals = new Interval[n];
		for (int i = 0; i < n; i ++) {
			line = stdin.readLine();
			st = new StringTokenizer(line);
			Interval interval = new Interval();
			interval.a = Integer.valueOf(st.nextToken())+1;
			interval.b = Integer.valueOf(st.nextToken())+2;
			intervals[i] = interval;
		}
		Arrays.sort(intervals);
		//如果interval1包含interval2，那么去掉interval1
		for (int i = 0; i < intervals.length; i ++) {
			for (int j = i+1; j < intervals.length; j ++) {
				if (intervals[i].contains(intervals[j])) {
					intervals[i] = null;
					break;
				}
			}
		}
		
		List<Edge> edges = new ArrayList<Edge>();
		Set<Integer> vs = new HashSet<Integer>();
		for (int i = 0; i < n; i ++) {
			if (intervals[i] != null) {
				Edge e = new Edge(intervals[i].b,intervals[i].a, -2);
				edges.add(e);
				vs.add(e.v);
				vs.add(e.u);
			}
			
		}
		//X[i] -X[0] <= 0
		for (Integer v: vs) {
			Edge e = new Edge();
			e.u = 0;
			e.v = v;
			e.w = 0;
			edges.add(e);
		}
		vs.add(0);
		int size = vs.size();
		Integer[] vis = vs.toArray(new Integer[size]);
		Arrays.sort(vis);
		/*
		 * i < j
		 * X[i] - X[j] <= 0 	
		 * X[j] - X[i] <= j-i
		 */
		for (int i = 1; i < size-1; i ++) {
			edges.add(new Edge(vis[i+1], vis[i], 0));
			edges.add(new Edge(vis[i], vis[i+1], vis[i+1]-vis[i]));
		}
		
		for (Edge e: edges) {
			e.u = Arrays.binarySearch(vis, e.u);
			e.v = Arrays.binarySearch(vis, e.v);
		}
		
//		Integer[] d = bellman_ford(size, edges);
		Integer[] d = spfa(size, edges);
		
		int min = d[1];
		int max = d[1];
		for (int i = 1; i < size; i ++) {
			if (min > d[i]) min = d[i];
			if (max < d[i]) max = d[i];
		}
		System.out.println(max-min);
	}
	
	private static class Interval implements Comparable<Interval> {
		int a;
		int b;
		public boolean contains(Interval o) {
			return this.a <= o.a && this.b >= o.b;
		}
		public int compareTo(Interval o) {
			return Integer.valueOf(a).compareTo(o.a);
		}
	}
	
	private static class Edge {
		int u;
		int v;
		int w;
		
		public Edge() {}
		public Edge(int u, int v, int w) {
			this.u = u;
			this.v = v;
			this.w= w;
		}
	}
	
	@SuppressWarnings("unchecked")
	private static Integer[] spfa(int N, List<Edge> edges) {
		
		List<Edge>[] es = new List[N];	//邻接表
		for (int i = 0; i < es.length; i ++) {
			es[i] = new ArrayList<Edge>();
		}
		for (Edge e: edges) {
			es[e.u].add(e);
		}

		//初始化估值d[]
		Integer[] d = new Integer[N];
		for (int i = 0; i < N; i ++) {
			d[i] = Integer.MAX_VALUE;
		}
		d[0] = 0;
		
		//更新估值d[]
		LinkedList<Integer> queue = new LinkedList<Integer>();
		queue.add(0);
		while (!queue.isEmpty()) {
			Integer u = queue.poll();
			for (Edge e: es[u]) {
				int v = e.v; 
				if (d[v] > d[u] + e.w) {
					d[v] = d[u] + e.w;
					if (!queue.contains(v)) {
						queue.add(v);
					}
				}
			}
		}
		return d;
	}
	
	private static Integer[] bellman_ford(int N, List<Edge> edges) {
		
		Integer[] d = new Integer[N];
		for (int i = 0; i < N; i ++) {
			d[i] = Integer.MAX_VALUE;
		}
		d[0] = 0;
		
		for (int i = 0; i < N; i ++) {
			for (Edge e: edges) {
				if (d[e.v] > d[e.u] + e.w) {
					d[e.v] = d[e.u] + e.w;
				}
			}
		}
		for (Edge e: edges) {
			if (d[e.v] > d[e.u] + e.w) {
				throw new RuntimeException();
			}
		}
		return d;
	}
}